import datetime
import os

from django.http import HttpResponse, HttpResponseNotFound, JsonResponse, StreamingHttpResponse, FileResponse
from django.shortcuts import render, redirect
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView

from app1.forms import StudentForm
from app1.models import StudentInfo

"""
子应用创建及视图控制流程：
第⼀步：创建子应⽤-----startapp 指令
第⼆步：注册应⽤到项⽬的settings.py----
     INSTALLED_APPS = [ "子应用名称.apps.子应用名称Config"   ]
第三步：编写模版⽹⻚代码html页面文件------xxxx.html
第四步：编写子应用的views.py视图处理请求层代码
    def 自定义（路由）函数名称(request):
        return render(request, 'xxx.html')
第五步：编写请求映射函数配置-----
    在主应用项⽬的urls.py⾥编写应⽤的 自定义（路由）函数名称/请求
    path('url路由名称/', 子应用名称.views.自定义（路由）函数名称)
第六步，启动项⽬，测试
    runserver 指令
    执行具体的URL路由地址
"""


# 定义⼈类
class Person:
    # 属性 姓名
    name = None
    # 属性 年龄
    age = None

    def __init__(self, name, age):
        self.name = name
        self.age = age


# Create your views here.
def index(request):
    str = "hello"
    date = datetime.datetime.now()
    myDict = {"tom": '666', 'cat': '999', 'wzw': '333'}
    # 创建⼀个对象 zhangsan
    zhangsan = Person("张三", 21)
    myList = ["java", "python", "c"]
    myTuple = ("python", 100, 3.14, False)
    content_value = {"msg": str, "msg2": myDict, "msg3": zhangsan, "msg4": myList, "msg5": myTuple, "date": date}
    return render(request, 'appIndex.html', context=content_value)
    # return render(request, 'index.html', context=content_value)

    """
    渲染并返回首页视图。
    参数:
    - request: HttpRequest对象，包含了用户请求的所有信息。
    返回:
    - HttpResponse对象，渲染index.html模板后返回给用户。
    """
    # 重定向
    # permanent --- 是否是永久重定向, 默认为False,
    # 如果为真，则返回301重定向。否则返回302重定向。
    # return redirect("/static/new.html", permanent=True)

    # print("app1视图函数index被调用了")
    # obj = {
    #     "name": "zhangsan",
    #     "age": 18
    # }
    # return render(request, 'appIndex.html', context=obj)

    # return render(request, 'app1.html')
    # html = "<h1>显示app1子应用中的index.html页面</h1>"
    # return HttpResponse(html, status=200)

    # return HttpResponseNotFound()
    # obj = {
    #     "name": "zhangsan",
    #     "age": 18
    # }
    # return JsonResponse(obj)


def to_course(request):
    return render(request, 'course.html')


# def blog(request,id):
#     print("app1视图函数blog被调用了",id)
#     # return render(request, 'appBlog.html')
#     return  HttpResponse('id是' + str(id) + "的博客⻚⾯")


# def blog(request,year,month,day,id):
#     print("app1视图函数blog被调用了",id)
#     # return render(request, 'appBlog.html')
#     return  HttpResponse('id是' + str(id) + "的博客⻚⾯"+str(year)+"/"+str(month)+"/"+str(day))


def blog(request, id):
    """
    请求博客页面的函数。
    参数:
    - request: HTTP请求对象，用于处理客户端的请求。
    - id: 博客的标识符，用于指定请求的博客页面。
    返回:
    - 如果id为0，则返回一个HTTP重定向到静态404页面。
    - 否则，返回一个包含博客id的HTTP响应。
    """
    # 检查博客标识符是否为0
    if id == 0:
        # 如果标识符为0，重定向到静态404页面
        return redirect("/static/page404.html")
    else:
        # 如果标识符不为0，返回一个包含博客标识符的HTTP响应
        return HttpResponse('id是' + str(id) + "的博客页面")


"""
Django提供三种⽅式实现⽂件下载功能，分别是HttpResponse、StreamingHttpResponse和
FileResponse
"""
file_path = "D:\\360zip_setup.zip"


# 1.使用HttpResponse响应下载文件
def download_file1(request):
    # 打开⽂件，以⼆进制读取⽅式，确保兼容性并处理⼤⽂件
    file = open(file_path, "rb")
    # 创建HttpResponse对象，⽤于封装响应内容和响应头
    response = HttpResponse(file)
    # 设置响应头，指定内容类型为⼆进制流，适⽤于所有类型的⽂件下载
    response["Content-Type"] = "application/octet-stream"
    # 设置响应头，指定⽂件下载⽅式为附件，并建议客户端保存的⽂件名为360zip_setup.zip
    response["Content-Disposition"] = "attachment;filename=360zip_setup1.zip"
    # 返回封装好的HttpResponse对象，供客户端下载⽂件
    return response


# 2.使用StreamingHttpResponse响应下载文件
def download_file2(request):
    # 打开⽂件，以⼆进制读取⽅式，确保兼容性并处理⼤⽂件
    file = open(file_path, "rb")
    # 创建HttpResponse对象，⽤于封装响应内容和响应头
    response = StreamingHttpResponse(file)
    # 设置响应头，指定内容类型为⼆进制流，适⽤于所有类型的⽂件下载
    response["Content-Type"] = "application/octet-stream"
    # 设置响应头，指定⽂件下载⽅式为附件，并建议客户端保存的⽂件名为360zip_setup.zip
    response["Content-Disposition"] = "attachment;filename=360zip_setup2.zip"
    # 返回封装好的HttpResponse对象，供客户端下载⽂件
    return response


# 3.使用FileResponse响应下载文件
def download_file3(request):
    # 打开⽂件，'rb'模式表示以⼆进制⽅式读取⽂件
    file = open(file_path, 'rb')
    # 创建FileResponse对象，⽤于将⽂件作为HTTP响应返回给客户端
    response = FileResponse(file)
    # 设置响应头，指定⽂件的Content-Type为'application/octet-stream'
    response['Content_Type'] = 'application/octet-stream'
    # 设置响应头，指定⽂件的下载⽅式为附件，并指定⽂件名为'file3.exe'
    response['Content-Disposition'] = 'attachment;filename=file3.zip'
    # 返回包含⽂件的HTTP响应对象
    return response


# http数据请求
def getData(request):
    # 打印请求的⽅法，以了解请求的类型（如GET、POST等）
    print("请求⽅式:", request.method)  # 请求⽅式
    # 以下是⼀些常⽤的请求属性，⽤于获取请求的详细信息
    # 打印内容类型，表示请求中发送的数据的媒体类型
    print("数据的媒体类型:", request.content_type)
    # 打印内容参数，表示内容类型的附加参数
    print("内容类型的附加参数:", request.content_params)
    # 打印Cookies，获取请求中发送的cookie信息
    print("cookie信息:", request.COOKIES)
    # 打印协议⽅案，显示请求使⽤的协议（如http、https）
    print("协议（如http、https）:", request.scheme)
    # 以下是⼀些常⽤的⽅法，⽤于获取请求的特定信息
    # 判断请求是否通过安全的⽅式发送（如https）
    print("判断请求是否通过安全的⽅式发送:", request.is_secure())
    # 获取主机名，即请求的服务器地址
    print("获取主机名:", request.get_host())
    # 获取完整的请求路径，包括URL路径和查询字符串
    print("获取完整的请求路径:", request.get_full_path())
    # 从GET请求中获取特定参数的值，如果没有该参数，则返回None
    print("从GET请求中获取特定参数的值:", request.GET.get("name"))
    print("从GET请求中获取特定参数的值:", request.GET.get("pwd"))
    # 尝试获取参数'aaa'的值，如果不存在，则返回默认值'666'
    print("尝试获取参数'aaa'的值:", request.GET.get("aaa", "666"))
    # 返回HTTP响应，表示请求处理成功
    return HttpResponse("http get ok")


def getDataDetails(request):
    return render(request, 'details.html')


def postData(request):
    # 打印请求的⽅法，以确认请求类型
    print("请求⽅式:", request.method)  # 请求⽅式
    # 打印POST数据中的'name'字段值，如果不存在，则返回None
    print("打印POST数据中的'name'字段值:", request.POST.get("name"))
    # 打印POST数据中的'pwd'字段值，如果不存在，则返回None
    print("打印POST数据中的'pwd'字段值:", request.POST.get("pwd"))
    # 尝试打印POST数据中的'aaa'字段值，如果不存在，则默认返回'666'
    print("尝试打印POST数据中的'aaa'字段值:", request.POST.get("aaa", "666"))
    # 返回HTTP响应，表示POST请求处理成功
    return HttpResponse("http post ok")


# 跳转到登录页面
def to_login(request):
    return render(request, 'login.html')


# 实现登录数据提交
def login(request):
    # 从请求中获取⽤户名和密码
    username = request.POST.get("user_name")
    password = request.POST.get("pwd")
    # print("用户名:", username)
    # print("密码:", password)
    # 检查⽤户名和密码是否匹配预设值
    if username == "admin" and password == "123456":
        # 在会话中存储⽤户名
        request.session['username'] = username
        # 登录成功，返回HTTP响应，表示登录成功
        response = render(request, 'main.html')
        # 设置Cookie，用于在客户端保存登录状态
        response.set_cookie("login_cookie", "abc123")
        return response
    else:
        # 登录失败，返回HTTP响应，表示登录失败
        # 准备错误信息字典
        content_value = {"error_info": '⽤户名或者密码错误！'}
        return render(request, 'login.html', context=content_value)


# 跳转到文件上传页面
def to_upload(request):
    # 渲染上传页面
    return render(request, 'upload.html')


# 文件的上传逻辑
def upload_file(request):
    # 获取上传的⽂件，如果没有⽂件，就默认为None
    myFile = request.FILES.get("myFile", None)
    if myFile:
        # 获取上传⽂件的原始名称
        file_name = myFile.name
        # print("上传⽂件的原始名称:", file_name)
        # 打开特定的⽂件进⾏⼆进制的写操作
        file_path = "D:\\myFile"
        # f = open(file_path + file_name, 'wb+')
        f = open(os.path.join(file_path, file_name), 'wb+')
        # 分块写⼊⽂件
        for chunk in myFile.chunks():
            f.write(chunk)
        # 关闭⽂件流
        f.close()
        # 返回⽂件上传成功的响应
        return HttpResponse("⽂件上传成功！")
    else:
        return HttpResponse("没有上传文件！")


# 学生信息列表展示
class List(ListView):
    # 设置模版⽂件
    template_name = 'student/list.html'
    # 设置模型外的数据
    extra_context = {'title': '学⽣信息列表'}
    # 查询结果集
    queryset = StudentInfo.objects.all()
    # 每⻚展示5条数据
    paginate_by = 5
    # 设置上下⽂对象名称
    context_object_name = 'student_list'


# 学生详情页信息
class Detail(DetailView):
    # 设置模版⽂件
    template_name = 'student/detail.html'
    # 设置模型外的数据
    extra_context = {'title': '学⽣信息详情'}
    # 设置查询模型
    model = StudentInfo
    # 设置上下⽂对象名称
    context_object_name = 'student'
    # 指定URL中⽤于获取对象的唯⼀标识符的参数名称，默认为’pk’。
    pk_url_kwarg = 'id'


# 添加学生信息
class Create(CreateView):
    # 设置模版⽂件
    template_name = 'student/create.html'
    # 设置模型外的数据
    extra_context = {'title': '学⽣信息添加'}
    # 指定form
    form_class = StudentForm
    # 执⾏成功后跳转地址
    success_url = '/student/list'


# 修改学生信息
class Update(UpdateView):
    # 设置模版⽂件
    template_name = 'student/update.html'
    # 设置模型外的数据
    extra_context = {'title': '学⽣信息编辑'}
    # 设置查询模型
    model = StudentInfo
    # 指定form
    form_class = StudentForm
    # 执⾏成功后跳转地址
    success_url = '/student/list'
    # 指定URL中⽤于获取对象的唯⼀标识符的参数名称，默认为’pk’。
    pk_url_kwarg = 'id'


# 删除学生信息
class Delete(DeleteView):
    # 设置模版⽂件
    template_name = 'student/delete.html'
    # 设置模型外的数据
    extra_context = {'title': '学⽣信息删除'}
    # 设置上下⽂对象名称
    context_object_name = 'student'
    # 设置查询模型
    model = StudentInfo
    # 执⾏成功后跳转地址
    success_url = '/student/list'
    # 指定URL中⽤于获取对象的唯⼀标识符的参数名称，默认为’pk’。
    pk_url_kwarg = 'id'
